package com.hinner.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hinner.common.Constant;
import com.hinner.common.Result;
import com.hinner.entity.PageBean;
import com.hinner.entity.SysRole;
import com.hinner.entity.SysUser;
import com.hinner.entity.SysUserRole;
import com.hinner.service.SysRoleService;
import com.hinner.service.SysUserRoleService;
import com.hinner.service.SysUserService;
import com.hinner.util.DateUtil;
import com.hinner.util.StringUtil;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.*;

@RestController
@RequestMapping("/sys/user")
public class SysUserController {

    @Autowired
    private SysUserService sysUserService;

    // 因为这个方法用@Bean被容器管理了，所以可以可直接注入
    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Value("${avatarImagesFilePath}")
    private String avatarImagesFilePath;

    @Autowired
    private SysRoleService sysRoleService;

    @Autowired
    private SysUserRoleService sysUserRoleService;

    /**
     * 更新用户、 新增用户接口
     * @param sysUser
     * @return
     */
    @PostMapping("/save")
    @PreAuthorize("hasAuthority('system:user:add')" + "||" + "hasAuthority('system:user:edit')")
    public Result save(@RequestBody SysUser sysUser){
        if (sysUser.getId() == null || sysUser.getId() == -1){
            //新增
            sysUser.setCreateTime(new Date());
            sysUser.setPassword(bCryptPasswordEncoder.encode(sysUser.getPassword()));
            sysUserService.save(sysUser);
        }else {
            //更新
            sysUser.setUpdateTime(new Date());
            sysUserService.updateById(sysUser);
        }
        return Result.success("操作成功");
    }


    /**
     * 更新密码
     * @param sysUser
     * @return
     */
    @PostMapping("/updateUserPwd")
    @PreAuthorize("hasAuthority('system:user:edit')")
    public Result updatePwd(@RequestBody SysUser sysUser){
        SysUser currentUser = sysUserService.getById(sysUser.getId());
        // 判断输入的旧密码是否和数据库一致，相同才能修改密码. 不要给新密码加密后再入库
        if (bCryptPasswordEncoder.matches(sysUser.getOldPassword(), currentUser.getPassword())) {
            currentUser.setPassword(bCryptPasswordEncoder.encode(sysUser.getNewPassword()));
            currentUser.setUpdateTime(new Date());
            sysUserService.updateById(currentUser);
            return Result.success("密码修改成功");
        }else {
            return Result.error("旧密码错误,请重新输入");
        }
    }

    /**
     * 前端上传文件到页面上的接口,不是入库的接口
     * @param file
     * @return
     */
    @PostMapping("/uploadImage")
    @PreAuthorize("hasAuthority('system:user:edit')")
    public Map<String, Object> uploadImage(MultipartFile file, HttpServletRequest request) throws IOException {
        Map<String, Object> resultMap = new HashMap<>();
        System.out.println("我是token="+request.getHeader("token"));
        if (!file.isEmpty()){
            // 文件名
            String filename = file.getOriginalFilename();
            // 后缀名
            String suffixName = filename.substring(filename.lastIndexOf("."));
            // 新文件名
            String newFileName = DateUtil.getCurrentDateStr()+suffixName;
            // 新文件地址
            File newFile = new File(avatarImagesFilePath + newFileName);
            // 将上传到内存的文件以流的形式写入到新文件中
            FileUtils.copyInputStreamToFile(file.getInputStream(),newFile);
            resultMap.put("code",0);
            resultMap.put("msg","上传成功");
            // 组装
            Map<String, Object> resData = new HashMap<>();
            resData.put("title", newFileName);
            resData.put("src", "image/useAvatar/"+newFileName);
            resultMap.put("data",resData);

        }
        return resultMap;
    }

    /**
     * 修改用户头像：主要是入库
     * @param sysUser
     * @return
     */
    @PostMapping("/updateAvatar")
    @PreAuthorize("hasAuthority('system:user:edit')")
    public Result updateAvatar(@RequestBody SysUser sysUser){
        SysUser currentUser = sysUserService.getById(sysUser.getId());
        currentUser.setUpdateTime(new Date());
        currentUser.setAvatar(sysUser.getAvatar());
        sysUserService.updateById(currentUser);
        return Result.success();
    }

    /**
     * 分页查询:这里用mp的分页
     * @param pageBean
     * @return
     */
    @PostMapping("/list")
    @PreAuthorize("hasAuthority('system:user:query')")
    public Result list(@RequestBody PageBean pageBean){
        String query = pageBean.getQuery().trim();
        Page<SysUser> pageResult = sysUserService.page(new Page<>(pageBean.getPageNum(), pageBean.getPageSize()),
                new QueryWrapper<SysUser>().like(StringUtil.isNotEmpty(query),"username",query));

        // 获取用户列表
        List<SysUser> userList = pageResult.getRecords();

        // 查询用户的角色
        if (CollectionUtil.isNotEmpty(userList)){
            for (SysUser sysUser : userList) {
                List<SysRole> roleList = sysRoleService.list(new QueryWrapper<SysRole>()
                        .inSql("id", "select role_id from sys_user_role where user_id = " + sysUser.getId()));
                sysUser.setSysRoleList(roleList);
            }
        }

        Map<String, Object> map = new HashMap<>();
        map.put("userList",userList);
        map.put("total",pageResult.getTotal());
        return Result.success(map);
    }


    /**
     * 给前端调用：根据id查询
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    @PreAuthorize("hasAuthority('system:user:query')")
    public Result findById(@PathVariable(value = "id")Integer id){
        SysUser sysUser = sysUserService.getById(id);
        return Result.success(sysUser);
    }

    /**
     * 给前端调用：验证用户名是否已经存在
     * @param sysUser
     * @return
     */
    @PostMapping("/checkUserName")
    @PreAuthorize("hasAuthority('system:user:query')")
    public Result checkUserName(@RequestBody SysUser sysUser){
        if(ObjectUtil.isNull(sysUserService.getUserByUserName(sysUser.getUsername()))){
            return Result.success();
        }else{
            return Result.error("用户名已存在");
        }
    }


    /**
     * 根据ids批量删除用户， 注意，同时也要删除对应的角色(维护在用户角色中间表中)
     * @param ids
     * @return
     */
    @Transactional
    @PostMapping("/delete")
    @PreAuthorize("hasAuthority('system:user:delete')")
    public Result delete(@RequestBody Long[] ids){
        //1.删除用户
        sysUserService.removeByIds(Arrays.asList(ids));
        //2，删除用户角色中间表中改用户的角色信息
        sysUserRoleService.remove(new QueryWrapper<SysUserRole>().in("user_id",ids));
        return Result.success("删除成功");
    }






    /**
     * 重置密码: 初始化密码是123456
     * @param id
     * @return
     */
    @GetMapping("/resetPassword/{id}")
    @PreAuthorize("hasAuthority('system:user:edit')")
    public Result resetPassword(@PathVariable(value = "id")Integer id){
        SysUser sysUser = sysUserService.getById(id);
        sysUser.setPassword(bCryptPasswordEncoder.encode(Constant.DEFAULT_PASSWORD));
        sysUser.setUpdateTime(new Date());
        sysUserService.updateById(sysUser);
        return Result.success();
    }





    /**
     * 更新status状态: 0正常，1禁用
     * @param id  哪个用户
     * @param status 修改新的状态值
     * @return
     */
    @GetMapping("/updateStatus/{id}/status/{status}")
    @PreAuthorize("hasAuthority('system:user:edit')")
    public Result updateStatus(@PathVariable(value = "id")Integer id,
                               @PathVariable(value = "status")String status){
        sysUserService.update(new UpdateWrapper<SysUser>().set("status",status).eq("id",id));
//        SysUser sysUser = sysUserService.getById(id);
//        sysUser.setStatus(status);
//        sysUserService.saveOrUpdate(sysUser);
        return Result.success();
    }



    /**
     * 用户角色授权
     * @param userId
     * @param roleIds
     * @return
     */
    @Transactional
    @PostMapping("/grantRole/{userId}")
    @PreAuthorize("hasAuthority('system:user:role')")
    public Result grantRole(@PathVariable("userId") Long userId,
                            @RequestBody Long[] roleIds){
        //用户角色中间表： 用户id - 多个角色id
        List<SysUserRole> userRoleList=new ArrayList<>();
        Arrays.stream(roleIds).forEach(r -> {
            SysUserRole sysUserRole = new SysUserRole();
            sysUserRole.setRoleId(r);
            sysUserRole.setUserId(userId);
            userRoleList.add(sysUserRole);
        });

        // 移除[用户角色中间表]中这个用户之前所有的角色信息
        sysUserRoleService.remove(new QueryWrapper<SysUserRole>
                ().eq("user_id",userId));
        // 重新维护 [用户角色中间表] 数据
        sysUserRoleService.saveBatch(userRoleList);
        return Result.success();
    }
}
